package com.effectiv.gooruda.rest.api.operation;

import java.util.List;

import javax.ws.rs.core.MediaType;

import com.effectiv.gooruda.rest.api.domain.Profile;
import com.effectiv.gooruda.rest.api.domain.Role;
import com.effectiv.gooruda.rest.api.domain.User;
import com.effectiv.gooruda.rest.docs.core.annotation.Api;
import com.effectiv.gooruda.rest.docs.core.annotation.ApiBodyObject;
import com.effectiv.gooruda.rest.docs.core.annotation.ApiHeader;
import com.effectiv.gooruda.rest.docs.core.annotation.ApiHeaders;
import com.effectiv.gooruda.rest.docs.core.annotation.ApiMethod;
import com.effectiv.gooruda.rest.docs.core.annotation.ApiParam;
import com.effectiv.gooruda.rest.docs.core.annotation.ApiRequestParam;
import com.effectiv.gooruda.rest.docs.core.annotation.ApiResponseObject;
import com.effectiv.gooruda.rest.docs.core.pojo.ApiVerb;



@Api(name = "User API", description = "User management API.")
public interface UserOperations {
	
	
	@ApiMethod(path = "/api/user", verb = ApiVerb.POST, description = "Saves user details.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })
	@ApiResponseObject
	User save(@ApiBodyObject User user);
	
	
	@ApiMethod(path = "/api/user/addrole/{userName}/{roleName}", verb = ApiVerb.POST, 
			description = "Adds a role to the user.Role must be present in the system otherwise API will report error.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	User addRole(@ApiParam(name = "userName", required = true, description = "User name.") String userName, 
			@ApiParam(name = "roleName", required = true, description = "Role name.") String roleName);
	
	
	@ApiMethod(path = "/api/user/addroles/{userName}/{roleNames}", verb = ApiVerb.POST, 
			description = "Adds multiple roles to the user.Roles must be present in the system otherwise API will report error.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	User addRoles(@ApiParam(name = "userName", required = true, description = "User name.") String userName, 
			@ApiParam(name = "roleNames", required = true, description = "Role names.") List<String> roleNames);
	
	@ApiMethod(path = "/api/user/authenticate/{userName}/{password}", verb = ApiVerb.POST, 
			description = "Authenticate an user based on user name and password.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	User authenticate(
			@ApiParam(name = "userName", required = true, description = "User name.") String userName, 
			@ApiParam(name = "password", required = true, description = "Password.") String password);
	
	
	@ApiMethod(path = "/api/user/authenticateandstartsession/{userName}/{password}", verb = ApiVerb.POST, 
			description = "Authenticate an user based on user name and password.It also starts a new session.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	User authenticateAndStartSession(
			@ApiParam(name = "userName", required = true, description = "User name.") String userName, 
			@ApiParam(name = "password", required = true, description = "Password.") String password);
	
	
	@ApiMethod(path = "/api/user/changepassword/{userName}/{oldPassword}/{newPassword}", verb = ApiVerb.POST, 
			description = "Changes user password.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	User changePassword(
			@ApiParam(name = "userName", required = true, description = "User name.") String userName, 
			@ApiParam(name = "oldPassword", required = true, description = "Old/existing password.") String oldPassword,
			@ApiParam(name = "newPassword", required = true, description = "New password.") String newPassword);
	
	
	@ApiMethod(path = "/api/user/findByUserName/{userName}", verb = ApiVerb.GET, 
			description = "Retrieves the details of an user by user name.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	User findByUserName(@ApiParam(name = "userName", required = true, description = "User name.") String userName);
	
	@ApiMethod(path = "/api/user/addorupdateprofile/{userName}", verb = ApiVerb.POST, 
			description = "Retrieves the details of an user by user name.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject

	User addOrUpdateProfile(
			@ApiParam(name = "userName", required = true, description = "User name.") String userName, 
			@ApiBodyObject Profile profile);
	
	@ApiMethod(path = "/api/user/deleteuser/{userName}", verb = ApiVerb.DELETE, 
			description = "Delete an user with the given user name.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	void deleteUser(@ApiParam(name = "userName", required = true, description = "User name.") String userName);
	
	
	@ApiMethod(path = "/api/user/findall", verb = ApiVerb.GET, 
			description = "Find all the users.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	List<User> findAll(
			@ApiRequestParam(name = "pageNo",  description = "Page number.", defaultValue="0") int pageNo, 
			@ApiRequestParam(name = "pageSize",  description = "Number of records to fetch for a page.", defaultValue="0") int pageSize);
	
	
	@ApiMethod(path = "/api/user/count", verb = ApiVerb.GET, 
			description = "Returns a count of the total number of users.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	long count();
	
	@ApiMethod(path = "/api/user/findlockedusers", verb = ApiVerb.GET, 
			description = "Finds a list of locked users.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	List<User> findLockedUsers(
			@ApiRequestParam(name = "pageNo",  description = "Page number.", defaultValue="0") int pageNo, 
			@ApiRequestParam(name = "pageSize",  description = "Number of records to fetch for a page.", defaultValue="0") int pageSize
			);
	
	@ApiMethod(path = "/api/user/countlockedusers", verb = ApiVerb.GET, 
			description = "Returns a count of the total number of locked users.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	long countLockedUsers();
	
	
	@ApiMethod(path = "/api/user/findrolesforUser/{userName}", verb = ApiVerb.GET, 
			description = "Returns the list of roles for a given user."
			, produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	List<Role> findRolesForUser(@ApiParam(name = "userName", required = true, description = "User name.") String userName);
	
	
	
	@ApiMethod(path = "/api/user/findone/{id}", verb = ApiVerb.GET, 
			description = "Finds an user by user id.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	User findOne(@ApiParam(name = "id", required = true, description = "User Id.")  String id);
	
	@ApiMethod(path = "/api/user/findbyemail/{email}", verb = ApiVerb.GET, 
			description = "Finds an user by email.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	User findByEmail(@ApiParam(name = "email", required = true, description = "Email of the user.")  String email);
	
	@ApiMethod(path = "/api/user/lock/{userName}", verb = ApiVerb.GET, 
			description = "Locks an user by user name.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	User lock(@ApiParam(name = "userName", required = true, description = "User name.") String userName);
	
	
	@ApiMethod(path = "/api/user/unlock/{userName}", verb = ApiVerb.GET, 
			description = "Unlocks an user by user name.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	User unlock(@ApiParam(name = "userName", required = true, description = "User name.") String userName);
	
	
	@ApiMethod(path = "/api/user/removeallroles/{userName}", verb = ApiVerb.GET, 
			description = "Removes all roles for an user.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject

	User removeAllRoles(@ApiParam(name = "userName", required = true, description = "User name.") String userName);
	
	@ApiMethod(path = "/api/user/updateemail/{userName}/{newEmail}", verb = ApiVerb.GET, 
			description = "Updates the email.", produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })	
	@ApiResponseObject
	User updateEmail(
			@ApiParam(name = "userName", required = true, description = "User name.") String userName, 
			@ApiParam(name = "newEmail", required = true, description = "New email.") String newEmail);
}
